package QuizPackage;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Random;


public class Quiz {
	
	public static String[] questionTypes = {"questionresponse","fillinblank", "pictureresponse", "multipleresponse","multiplechoice"};
	public static String[] quizCategories = {"Math","English","Science","History","Fun","Miscellaneous"};
	public static final long RECENT_TIME=86400000;

	private ArrayList<Question> questions;
	private int quizID;
	private String quizName;
	private String creator;
	private boolean random;
	private boolean singlePage;
	private boolean immediateCorrection;
	private boolean practice;
	public boolean canPractice;
	private boolean transition;
	private boolean reviewMode;
	ArrayList<Integer> timesCorrectPractice;
	String description;
	boolean started = false;
	int pos = 0;
	Date startDate=null;
	Date endDate=null;
	int score = 0;
	int possible = 0;
	
	/*public Quiz(String quizName,String creator)
	{
		this.quizName = quizName;
		this.creator = creator;
		getInfoFromDB(quizName,creator);
	}*/
	
	public Quiz(int quizID)
	{
		this.quizID = quizID;
		practice = false;
		reviewMode=false;
		try {
			getInfoFromDB(quizID);
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	//TODO IMPLEMENT
	private void getInfoFromDB(int quizID) throws SQLException
	{
		QuizDBC conn = new QuizDBC();
		ResultSet rs = conn.getQuiz(quizID);
		
		rs.next();
		quizName = rs.getString("name");
		creator = rs.getString("creator");
		random = Integer.parseInt(rs.getString("random")) == 1;
		singlePage = Integer.parseInt(rs.getString("singlepage")) == 1;
		canPractice = Integer.parseInt(rs.getString("practice")) == 1;
		immediateCorrection = Integer.parseInt(rs.getString("correction")) == 1;
		description = rs.getString("description");
		
		/*//System.out.println(random);
		//System.out.println(singlePage);
		//System.out.println(immediateCorrection);*/
		
		questions = new ArrayList<Question>();
		
		int currID=0;
		for(int i = 0 ; i < questionTypes.length ; i++)
		{
			ResultSet qset = conn.getQuestions(questionTypes[i],quizID);
			while(qset.next())
			{
				questions.add(formQuestion(currID,questionTypes[i],qset));
				currID++;
			}
		}
		
		if(random)
		{
			randomizeOrder();
		}
		
		//for(int i = 0 ; i<questions.size() ; i++) //System.out.println(questions.get(i));
	}
	
	public Question formQuestion(int questionID,String questionType,ResultSet qset) throws SQLException
	{
		if(questionType.equals("questionresponse"))
		{
			QuestionResponse q = new QuestionResponse(questionID,qset);
			return q;
		}
		if(questionType.equals("fillinblank"))
		{
			FillInBlank q = new FillInBlank(questionID,qset);
			return q;
		}
		if(questionType.equals("pictureresponse"))
		{
			PictureResponse q = new PictureResponse(questionID,qset);
			return q;
		}
		if(questionType.equals("multipleresponse"))
		{
			MultiAnswer q = new MultiAnswer(questionID,qset);
			return q;
		}
		if(questionType.equals("multiplechoice"))
		{
			MultipleChoice q = new MultipleChoice(questionID,qset);
			return q;
		}
		return null;
	}
	
	public void setPracticeMode(boolean practice)
	{
		this.practice=practice;
		timesCorrectPractice = new ArrayList<Integer>();
		if(singlePage) transition=false;
		//singlePage=false;
		for(int i=0 ; i < questions.size() ; i++)
		{
			timesCorrectPractice.add(0);
		}
	}
	
	public void setReviewMode(boolean review) {
		singlePage=true;
		immediateCorrection=true;
		reviewMode=true;
	}
	
	public boolean isReview()
	{
		return reviewMode;
	}
	
	public boolean isPractice()
	{
		return practice;
	}
	
	/*public Quiz(boolean random, boolean singlePage, boolean immediateCorrection)
	{
		this.random = random;
		this.singlePage = singlePage;
		this.immediateCorrection = immediateCorrection;
		questions = new ArrayList<Question>();
	}*/
	
	/*public void addQuestion(Question question)
	{
		if(started)
		{
			throw new RuntimeException("Quiz already started.");
		}
		questions.add(question);
	}*/
	
	private void randomizeOrder()
	{
		Random rand = new Random();
		for(int i = 0 ; i < questions.size() ; i++)
		{
			int randInt = rand.nextInt(questions.size() - i);
			Question temp = questions.get(i);
			questions.set(i, questions.get(randInt+i));
			questions.set(randInt+i,temp);
			/*if(practice)
			{
				Integer temp2 = timesCorrectPractice.get(i);
				timesCorrectPractice.set(i,timesCorrectPractice.get(randInt+i));
				timesCorrectPractice.set(randInt+i,temp2);
			}*/
		}
	}
	
	public void startQuiz()
	{
		startDate = new Date();
		started = true;
	}
	
	public boolean isStarted()
	{
		return started;
	}
	
	public Question nextQuestion()
	{
		if(transition) 
		{
			transition = false;
			return null;
		}
		Question q = null;
		if(pos < questions.size())
		{
			q = questions.get(pos);
			pos++;
			if(pos >= questions.size() && practice) 
			{
				pos=0;
				if(singlePage) transition = true;
				if(random) randomizeOrder();
			}
		}
		return q;
	}
	
	public Question getQuestion(int questionID)
	{
		for(int i = 0 ; i < questions.size() ; i++)
		{
			if(questions.get(i).questionID==questionID) return questions.get(i);
		}
		return null;
	}
	
	public boolean singlePage()
	{
		return singlePage;
	}
	
	public boolean immediateCorrection()
	{
		return immediateCorrection;
	}
	
	//TODO Should this attach score to particular questions?
	public void recordScore(int score,int possible,int questionID)
	{
		this.score += score;
		this.possible += possible;
		if(practice)
		{
			if(score==possible) 
			{
				int update = timesCorrectPractice.get(questionID)+1;
				timesCorrectPractice.set(questionID,update);
				if(update>=3) 
				{
					for(int i=0 ; i < questions.size() ; i++)
					{
						if(questions.get(i).questionID == questionID) 
						{
							questions.remove(i);
							if(pos >= questions.size() && practice) 
							{
								pos=0;
								if(singlePage) transition = true;
								if(random) randomizeOrder();
							}
						}
					}
				}
			}
		}
	}
	
	public void endQuiz()
	{
		if(!started) return;
		endDate = new Date();
		
		/*started = false;
		pos = 0;
		score = 0;
		possible = 0*/
	}
	
	public String getName()
	{
		return quizName;
	}
	
	public int getScore()
	{
		return score;
	}
	
	public int getTotal()
	{
		return possible;
	}
	
	public int getTime()
	{
		return (int) ((endDate.getTime()-startDate.getTime())/1000);
	}
	
	public String getDescription()
	{
		return description;
	}
	
	public String getCreator()
	{
		return creator;
	}
	
	/*public static void main(String[] args)
	{
		Quiz q = new Quiz(0);
	}*/
}
